package stud.mpgame.server.game;

import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import stud.mpgame.net.command.ArrowKeyCommand;
import stud.mpgame.network.Message;
import stud.mpgame.network.UserObject;
import stud.mpgame.physics.Circle;
import stud.mpgame.physics.Vector2D;
import stud.mpgame.snapshot.IGameObject;

import java.util.Vector;

public class Player extends UserObject implements IGameObject {

    private static final int NUMBER_OF_PROCESSED_KEYS = 4;
    private static final float VELOCITY = 0.2f;

    //0 - up, 1 - right, 2 - down, 3 - left
    private boolean[] pressed = new boolean[NUMBER_OF_PROCESSED_KEYS];

    private Circle circle;

    private int id;
    private IoSession session;

    public Player(float x, float y, IoSession session, int id) {
        for(int i = 0; i < pressed.length; i++)
            pressed[i] = false;
        this.id = id;

        this.session = session;

        this.circle = new Circle(x, y, 32, new Vector2D(0.0f, 0.0f));
    }

    public Player(Player previous) {
        this.circle = new Circle(previous.getX(), previous.getY(), 32, new Vector2D(previous.getVelocityX(), previous.getVelocityY()));
        this.id = previous.id;
        this.session = previous.session;

        System.arraycopy(previous.pressed, 0, pressed, 0, pressed.length);
    }

    public IoSession getSession() {
        return session;
    }

    public int getID() {
        return id;
    }

    public float getX() {
        return circle.x;
    }

    public float getY() {
        return circle.y;
    }

    public float getVelocityX() {
        return circle.velocity.x;
    }

    public float getVelocityY() {
        return circle.velocity.y;
    }

    public Circle getCircle() {
        return circle;
    }

    public void update(int deltaTime) {
//        float x = circle.x;
//        float y = circle.y;

//        float vel = 0.2f;
//        //0 - up, 1 - right, 2 - down, 3 - left
//        if ( pressed[0] && !pressed[2] )
//            circle.y -= vel * deltaTime;
//        else if ( pressed[2] && !pressed[0] )
//            circle.y += vel * deltaTime;
//        else if ( pressed[1] && !pressed[3] )
//            circle.x += vel * deltaTime;
//        else if ( pressed[3] && !pressed[1] )
//            circle.x -= vel * deltaTime;

        circle.x += deltaTime * circle.velocity.x;
        circle.y += deltaTime * circle.velocity.y;

//        if ( x != circle.x || y != circle.y )
//            System.out.println("changed: " + x + "; " + y);
    }

    public void applyArrowKeyCommand(ArrowKeyCommand arrowKeyCommand) {
        int currentKey = arrowKeyCommand.getKeyCode();
        boolean keyStatus = arrowKeyCommand.getKeyStatus();

        //0 - up, 1 - right, 2 - down, 3 - left
        pressed[currentKey] = keyStatus;

        if ( pressed[0] )
        {
            circle.velocity.y = -1.2f * VELOCITY;
            pressed[0] = false;
        }

        if ( pressed[1] && !pressed[3] )
            circle.velocity.x = VELOCITY;
        else if ( !pressed[1] && pressed[3] )
            circle.velocity.x = -VELOCITY;
        else
            circle.velocity.x = 0;

/*
        circle.velocity.x = 0.0f;
        circle.velocity.y = 0.0f;

        if ( pressed[0] && !pressed[2] )
            circle.velocity.y = -VELOCITY;
        else if ( pressed[2] && !pressed[0] )
            circle.velocity.y = VELOCITY;
        else if ( pressed[1] && !pressed[3] )
            circle.velocity.x = VELOCITY;
        else if ( pressed[3] && !pressed[1] )
            circle.velocity.x = -VELOCITY;
*/

//        if (pressed[currentKey] != keyStatus) {
//			pressed[currentKey] = keyStatus;
//			float velocityAbs = (float)0.2;
//			if(!keyStatus)
//				velocityAbs = -velocityAbs;
//
//            if ((currentKey & 1) == 0 && circle.velocity.y == 0 && !keyStatus)
//				return;
//
//			switch(currentKey) {
//				case 0 : circle.velocity.addDot(0, -velocityAbs); break;
//				case 1 : circle.velocity.addDot(velocityAbs, 0); break;
//				case 2 : circle.velocity.addDot(0, velocityAbs);  break;
//				case 3 : circle.velocity.addDot( -velocityAbs, 0); break;
//			}
//		}
    }

    @Override
    public void writeExternal(IoBuffer buffer, Message owner) {
    	buffer.putInt(id);
    	buffer.putFloat(circle.x);
    	buffer.putFloat(circle.y);
        buffer.putFloat(circle.velocity.x);
        buffer.putFloat(circle.velocity.y);
    }

	public void model(int deltaTime) {

	}
}

